#include "arexpres.h"
AriphmeticExpression::AriphmeticExpression (string s)
{
	head = 0;
	SetPriority();
	SetExpression(s);
}
AriphmeticExpression::~AriphmeticExpression()
{
	delete head;
}
double AriphmeticExpression::F(double x)
{
	return head->F(x);
}
void AriphmeticExpression::SetExpression(string s)
{
	BuildExpression(s);
	size_t nowPos = 0;
	delete head;
	head = BuildTree(nowPos,0);
	while(nowPos < size_)
	{
		string s = expression[nowPos];
		++nowPos;
		head = Typer::newFunction(head, BuildTree(nowPos, priority[expression[nowPos]]), s);
	}
}
void AriphmeticExpression::SetPriority()
{
	priority["("]=4;
	priority[")"]=4;
	priority["*"]=2;
	priority["/"]=2;
	priority["+"]=1;
	priority["-"]=1;
}
double GetNumber(stringstream & exp, string & expres )
{
	double x;
	exp >> x;
	exp >> expres;
	return x;
}
string GetOperator(string & expres)
{
	string op;
	op += expres[0];
	expres.erase(0,1);
	return op;
}
string GetMarking(string & expres)
{
	string mark;
	mark += expres[0];
	expres.erase(0,1);
	return mark;
}
void AriphmeticExpression::BuildExpression(string expres)
{
	size_t i = 0;
	for(i = 0; i < MAXN; ++i)
	{
		isMarking[i] = 0;
		isOperator[i] = false;
		isValue[i] = false;
		isVar[i] = false;
	}
	i = 0;
	string s;
	do
	{
		stringstream exp(stringstream::in | stringstream::out);
		exp << expres;
		if(expres[0] == '(')
		{
			expression[i] = GetMarking(expres);
			isMarking[i] = 1;
			++i;
			continue;
		}

		s = expres;
		if(expres[0]=='X' || expres[0]=='x')
		{
			expression[i] = GetOperator(expres);
			isVar[i] =true;
		}
		else
		{
			values[i] = GetNumber(exp, expres);
			isValue[i] = true;
		}
		++i;
		if(s == expres) break;
		if(expres == "") break;

		if(expres[0] == ')')
		{
			while(expres != "" && expres[0] == ')')
			{
				expression[i] = GetMarking(expres);
				isMarking[i] = 2;
				++i;
			}
		}
		if(expres == "") break;
		expression[i] = GetOperator( expres);
		isOperator[i] = true;
		++i;
	}while(expres!="" && s != expres);
	size_ = i;
}
Function* AriphmeticExpression::BuildTree(size_t & nowPos, int nowPrior)
{
	Function * num = 0;
	while(nowPos < size_)
	{
		if(isValue[nowPos])
		{
			num = Typer::newFunction(values[nowPos]);
			++nowPos;
			continue;
		}
		if(isVar[nowPos])
		{
			num = Typer::newFunction();
			++nowPos;
			continue;
		}
		if(isMarking[nowPos] == 1)
		{
			++nowPos;
			return BuildTree(nowPos, 0);
		}
		if(isMarking[nowPos] == 2)
		{
			++nowPos;
			return num;
		}
		if(isOperator[nowPos])
		{
			string s = expression[nowPos];
			if(priority[expression[nowPos]] > nowPrior)
			{
				++nowPos;
				num =  Typer::newFunction(num, BuildTree(nowPos, priority[expression[nowPos-1]]), s);
			}
			else
			{
				return num;
			}
		}
	}
	return num;
}